package com.xc.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xc.common.Const;
import com.xc.common.ServerResponse;
import com.xc.dao.AgentUserMapper;
import com.xc.dao.UserMapper;
import com.xc.dao.UserWithdrawMapper;
import com.xc.pojo.*;
import com.xc.service.*;
import com.xc.utils.stock.WithDrawUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.Server;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * @author mipha
 * @version 1.0
 * @date 2019/2/16 3:06 PM
 */
@Service("iUserWithdrawService")
@Slf4j
public class UserWithdrawServiceImpl implements IUserWithdrawService {

    @Autowired
    UserWithdrawMapper userWithdrawMapper;
    @Autowired
    IUserService iUserService;
    @Autowired
    UserMapper userMapper;
    @Autowired
    IAgentUserService iAgentUserService;
    @Autowired
    AgentUserMapper agentUserMapper;
    @Autowired
    IUserPositionService iUserPositionService;
    @Autowired
    IUserBankService iUserBankService;
    @Autowired
    ISiteSettingService iSiteSettingService;


    @Override
    @Transactional
    public ServerResponse outMoney(String amt, HttpServletRequest request) throws Exception{
        if(StringUtils.isBlank(amt)){
            return ServerResponse.createByErrorMsg("参数不能为空");
        }

        User user = iUserService.getCurrentRefreshUser(request);

        //  判断当前是否有持仓订单
        List<UserPosition> userPositions = iUserPositionService
                .findPositionByUserIdAndSellIdIsNull(user.getId());
        if(userPositions.size() > 0){
            return ServerResponse.createByErrorMsg("有持仓单不能出金");
        }

        //  未实名认证 和 添加银行卡不能提现
        if(StringUtils.isBlank(user.getRealName()) || StringUtils.isBlank(user.getIdCard())){
            return ServerResponse.createByErrorMsg("未实名认证");
        }
        UserBank userBank = iUserBankService.findUserBankByUserId(user.getId());
        if(userBank == null){
            return ServerResponse.createByErrorMsg("未添加银行卡");
        }

        //  用户被锁定 或模拟用户不能出金
//        if(user.getIsLock() == Const.UserLockStatus.lock){
//            return ServerResponse.createByErrorMsg("您的账户被锁定，请先联系解锁");
//        }
        if(user.getAccountType() == Const.UserAccountType.moni){
            return ServerResponse.createByErrorMsg("模拟用户不能出金");
        }

        //  提现金额不得小于设置表 最小金额
        SiteSetting siteSetting = iSiteSettingService.getSiteSetting();
        if(new BigDecimal(amt).compareTo(new BigDecimal(siteSetting.getWithMinAmt())) == -1){
            return ServerResponse.createByErrorMsg("出金金额不得低于" + siteSetting.getWithMinAmt() + "元");
        }

        //  判断出金时间
        int with_time_begin = siteSetting.getWithTimeBegin();
        int with_time_end = siteSetting.getWithTimeEnd();
        if(!WithDrawUtils.checkIsWithTime(with_time_begin,with_time_end)){
            return ServerResponse.createByErrorMsg("出金失败，出金时间在" + with_time_begin + "点 - " + with_time_end + "点 之间");
        }

        //  判断用户可用资金
        BigDecimal enable_amt = user.getEnableAmt();
        int compareAmt = enable_amt.compareTo(new BigDecimal(amt));
        if(compareAmt == -1){
            return ServerResponse.createByErrorMsg("提现失败，用户可用资金不足");
        }

        //  1。修改用户资金
        BigDecimal user_all_amt = user.getUserAmt();
        BigDecimal reckon_all_amt = user_all_amt.subtract(new BigDecimal(amt));
        BigDecimal reckon_enable_amt = enable_amt.subtract(new BigDecimal(amt));
        user.setUserAmt(reckon_all_amt);
        user.setEnableAmt(reckon_enable_amt);
        log.info("用户提现{}，金额 = {},总资金 = {},可用资金 = {}" , user.getId()
                , amt , user_all_amt , enable_amt);
        log.info("提现后，总金额={},可用资金={}" , reckon_all_amt , reckon_enable_amt);
        int updateUserCount = userMapper.updateByPrimaryKeySelective(user);
        if(updateUserCount > 0){
            log.info("修改用户资金成功");
        }else{
            log.error("修改用户资金失败");
            throw new Exception("用户提现，修改用户资金失败");
        }

        //  2。保存提现记录
        UserWithdraw userWithdraw = new UserWithdraw();
        userWithdraw.setUserId(user.getId());
        userWithdraw.setNickName(user.getRealName());
        userWithdraw.setAgentId(user.getAgentId());
        userWithdraw.setWithAmt(new BigDecimal(amt));
        userWithdraw.setApplyTime(new Date());
        userWithdraw.setWithName(user.getRealName());
        userWithdraw.setBankNo(userBank.getBankNo());
        userWithdraw.setBankName(userBank.getBankName());
        userWithdraw.setBankAddress(userBank.getBankAddress());
        userWithdraw.setWithStatus(Const.UserWithdrawStatus.apply_status);

        BigDecimal withfee = siteSetting.getWithFeePercent().multiply(new BigDecimal(amt))
                .add(new BigDecimal(siteSetting.getWithFeeSingle()));
        userWithdraw.setWithFee(withfee);

        int insertCount = userWithdrawMapper.insert(userWithdraw);
        if(insertCount > 0){
            return ServerResponse.createBySuccessMsg("提现成功");
        }else{
            log.error("保存提现记录失败");
            throw new Exception("用户提现，保存提现记录失败");
        }

    }

    @Override
    public ServerResponse<PageInfo> findUserWithList(String withStatus, HttpServletRequest request, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum,pageSize);

        User user = iUserService.getCurrentUser(request);

        List<UserWithdraw> userWithdraws = userWithdrawMapper
                .findUserWithList(user.getId() , withStatus);

        PageInfo pageInfo = new PageInfo(userWithdraws);

        return ServerResponse.createBySuccess(pageInfo);
    }

    @Override
    public synchronized ServerResponse userCancel(Integer withId) {
        if(withId == null){
            return ServerResponse.createByErrorMsg("id不能为空");
        }

        UserWithdraw userWithdraw = userWithdrawMapper.selectByPrimaryKey(withId);
        if(userWithdraw == null){
            return ServerResponse.createByErrorMsg("订单不存在");
        }

        //  如果不为 申请中的状态 就不能更改
        if(Const.UserWithdrawStatus.apply_status != userWithdraw.getWithStatus()){
            return ServerResponse.createByErrorMsg("当前订单不能取消");
        }

        //  修改状态为取消，反还用户金额
        userWithdraw.setWithStatus(Const.UserWithdrawStatus.apply_cancel);
        userWithdraw.setWithMsg("用户取消出金");
        int updateCount = userWithdrawMapper.updateByPrimaryKeySelective(userWithdraw);
        if(updateCount > 0){
            log.info("修改用户提现订单 {} 状态成功" ,withId );

            User user = userMapper.selectByPrimaryKey(userWithdraw.getUserId());
            user.setUserAmt(user.getUserAmt().add(userWithdraw.getWithAmt()));
            user.setEnableAmt(user.getEnableAmt().add(userWithdraw.getWithAmt()));
            int updateUserCount = userMapper.updateByPrimaryKeySelective(user);
            if(updateUserCount > 0){
                log.info("反还用户资金，总 {} 可用 {}",user.getUserAmt(),user.getEnableAmt());
                return ServerResponse.createBySuccessMsg("取消成功");
            }else{
                return ServerResponse.createByErrorMsg("取消失败");
            }
        }else{
            log.info("修改用户提现订单 {} 状态失败" ,withId );
            return ServerResponse.createByErrorMsg("取消失败");
        }

    }

    @Override
    public ServerResponse listByAgent(Integer agentId, String realName, Integer state, HttpServletRequest request, int pageNum, int pageSize) {
        //  当前登陆代理
        AgentUser currentAgent = iAgentUserService.getCurrentAgent(request);

        //  如果传入了agentId,首先判断agentId是否为当前代理下
        if(agentId != null){
            AgentUser agentUser = agentUserMapper.selectByPrimaryKey(agentId);
            if(agentUser.getParentId() != currentAgent.getId()){
                return ServerResponse.createByErrorMsg("不能查询非下级代理记录");
            }
        }
        Integer searchId = null;
        if(agentId == null){
            searchId = currentAgent.getId();    //  如果传入id为空，查询登陆代理的用户
        }else{
            searchId = agentId;
        }

        PageHelper.startPage(pageNum,pageSize);

        List<UserWithdraw> userWithdraws = userWithdrawMapper
                .listByAgent(searchId,realName,state);

        PageInfo pageInfo = new PageInfo(userWithdraws);

        return ServerResponse.createBySuccess(pageInfo);
    }

    @Override
    public ServerResponse<PageInfo> listByAdmin(Integer agentId, Integer userId, String realName
            , Integer state, String beginTime, String endTime, HttpServletRequest request, int pageNum, int pageSize) {

        PageHelper.startPage(pageNum,pageSize);

        List<UserWithdraw> userWithdraws = userWithdrawMapper
                .listByAdmin(agentId,userId,realName,state,beginTime,endTime);

        PageInfo pageInfo = new PageInfo(userWithdraws);

        return ServerResponse.createBySuccess(pageInfo);
    }

    @Override
    public ServerResponse updateState(Integer withId, Integer state, String authMsg) throws Exception {

        UserWithdraw userWithdraw = userWithdrawMapper.selectByPrimaryKey(withId);
        if(userWithdraw == null){
            return ServerResponse.createByErrorMsg("提现订单不存在");
        }

        if(userWithdraw.getWithStatus() != Const.UserWithdrawStatus.apply_status){
            return ServerResponse.createByErrorMsg("提现订单已处理，不要重复操作");
        }

        if(state == Const.UserWithdrawStatus.trans_fail){
            if(StringUtils.isBlank(authMsg)){
                return ServerResponse.createByErrorMsg("失败信息必填");
            }
        }

        //  1.  修改用户资金
        if(state == Const.UserWithdrawStatus.trans_fail){
            //  如果提现失败，就返还用户资金
            User user = userMapper.selectByPrimaryKey(userWithdraw.getUserId());
            if(user == null){
                return ServerResponse.createByErrorMsg("用户不存在");
            }
            BigDecimal user_amt = user.getUserAmt().add(userWithdraw.getWithAmt());
            log.info("管理员确认提现订单失败，返还用户 {} 总资金，原金额 = {} , 返还后 = {}" , user.getId() , user.getUserAmt() , user_amt);
            user.setUserAmt(user_amt);
            BigDecimal user_enable_amt = user.getEnableAmt().add(userWithdraw.getWithAmt());
            log.info("管理员确认提现订单失败，返还用户 {} 可用资金，原金额 = {} , 返还后 = {}" , user.getId() , user.getEnableAmt() , user_enable_amt);
            user.setEnableAmt(user_enable_amt);

            int updateCount = userMapper.updateByPrimaryKeySelective(user);
            if(updateCount > 0){
                log.info("提现失败，返还用户资金成功！");
            }else{
                log.error("返还用户资金出错，抛出异常");
                throw new Exception("修改用户资金出错，抛出异常");
            }

            //  提现失败，修改失败信息
            userWithdraw.setWithMsg(authMsg);
        }

        //  2.  修改订单
        userWithdraw.setWithStatus(state == Const.UserWithdrawStatus.trans_success
                ? Const.UserWithdrawStatus.trans_success
                : Const.UserWithdrawStatus.trans_fail);
        userWithdraw.setTransTime(new Date());

        int updateCount = userWithdrawMapper.updateByPrimaryKeySelective(userWithdraw);
        if(updateCount > 0){
            return ServerResponse.createBySuccessMsg("操作成功！");
        }else{
            return ServerResponse.createByErrorMsg("操作失败！");
        }

    }

    @Override
    public BigDecimal CountSpWithSumAmtByState(Integer withState) {
        return userWithdrawMapper.CountSpWithSumAmtByState(withState);
    }


}
